package com.gupao.p7store.common.utils.git;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.gupao.p7store.common.exception.ServiceException;
import com.gupao.p7store.common.utils.HttpUtils;
import com.gupao.p7store.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: git 操作工具类
 * 接口地址：https://gitlab.gupao.com/help
 * @author: dengbicheng
 * @create: 2021-12-13 20:03
 **/
@Slf4j
public class GitUtils {

    private final static String SZ_GIT = "gupao";

    private final static String TZ_GIT = "gupao";

    /**
     * git api 接口请求地址
     */
    private final static Map<String, String> URL_MAP = ImmutableMap.of(SZ_GIT, "https://gitlab.gupao.com/api/v4/",
        TZ_GIT, "https://gitlab.gupao.com/api/v4/");

    /**
     * 获取project列表接口路径
     */
    private final static String GIT_PROJECT_GET = "projects";

    private final static String GIT_BRANCH_GET = "projects/{projectId}/repository/branches/{branch}";

    private final static String GIT_TAG_GET = "projects/{projectId}/repository/tags/{tagName}";

    /**
     * 创建tag接口路径
     */
    private final static String GIT_TAG_CREATE = "projects/{projectId}/repository/tags";

    /**
     * 获取指定项目指定分支下指定文件的详情
     */
    private final static String GIT_FILE = "projects/{projectId}/repository/files/{filePath}?ref={branch}";

    private static String gpToken;

    private static String gupaoToken;

    /**
     * 前端配置模板git地址
     */
    private static String frontendConfigGitUrl;

    /**
     * 前端配置模板应用名称
     */
    private static String frontendConfigApplicationName;

    /**
     * 打tag
     */
    public static void addTag(GitTagCreateDto dto) {
        // 获取真正的git api地址
        String realGitUrl = getRealGitUrl(dto.getGitUrl());

        String projectId = dto.getProjectId();
        String branch = dto.getBranch();
        String tagName = dto.getTagName();
        String tagDesc = dto.getTagDesc();

        String requestUrl = realGitUrl + GIT_TAG_CREATE;
        requestUrl = requestUrl.replace("{projectId}", projectId);

        // 设置请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("PRIVATE-TOKEN", getToken(requestUrl));

        // 设置请求参数
        Map<String, Object> params = new HashMap<>(4);
        params.put("id", projectId);
        params.put("tag_name", tagName);
        params.put("ref", branch);
        params.put("message", tagDesc);

        HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(params, httpHeaders);

        ResponseEntity<String> exchange = HttpUtils.exchange(requestUrl, HttpMethod.POST, httpEntity, String.class);
        log.info(exchange.getBody());
    }

    /**
     * 根据应用服务名称查询git的应用服务id
     *
     * @return key：应用服务名称  value：应用服务git id
     */
    public static Map<String, String> search(String applicationName, String gitUrl) {
        // 获取真正的git api地址
        String realGitUrl = getRealGitUrl(gitUrl);

        if (StringUtils.isEmpty(applicationName)) {
            return Maps.newHashMap();
        }
        String requestUrl = realGitUrl + GIT_PROJECT_GET + "?search=" + applicationName;
        Map<String, String> header = new HashMap<>(1);
        header.put("PRIVATE-TOKEN", getToken(requestUrl));
        ResponseEntity<String> responseEntity = HttpUtils.get(requestUrl, header, String.class);
        JSONArray objects = JSONArray.parseArray(responseEntity.getBody());
        assert objects != null;
        Map<String, String> applicationMap = new HashMap<>(objects.size());
        for (Object object : objects) {
            JSONObject jsonObject = JSONObject.parseObject(object.toString());
            applicationMap.put(jsonObject.getString("name"), jsonObject.getString("id"));
        }
        return applicationMap;
    }

    private static String getToken(String url) {
        return url.startsWith("https://gitlab.gupao.com") ? gpToken : gupaoToken;
    }

    /**
     * 判断是否存在该分支
     *
     * @param projectId 应用服务git id
     * @param branch    分支名
     * @return true 存在该分支  false   不存在该分支
     */
    public static boolean isExistsBranch(String projectId, String branch, String gitUrl) {
        log.info("projectId: {}, branch: {}", projectId, branch);
        // 获取真正的git api地址
        String realGitUrl = getRealGitUrl(gitUrl);
        String requestUrl = realGitUrl + GIT_BRANCH_GET;
        requestUrl = requestUrl.replace("{projectId}", projectId);
        requestUrl = requestUrl.replace("{branch}", branch);
        Map<String, String> header = new HashMap<>(1);
        header.put("PRIVATE-TOKEN", getToken(requestUrl));
        try {
            ResponseEntity<String> responseEntity = HttpUtils.get(requestUrl, header, String.class);
            return responseEntity.getStatusCode().is2xxSuccessful();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断是否存在该标签
     *
     * @param gitProjectId 应用服务git id
     * @param tagName      标签名
     * @return true 存在该标签  false   不存在该标签
     */
    public static boolean isExistsTag(String gitProjectId, String tagName, String gitUrl) {
        log.info("projectId: {}, 标签: {}", gitProjectId, tagName);
        // 获取真正的git api地址
        String realGitUrl = getRealGitUrl(gitUrl);
        String requestUrl = realGitUrl + GIT_TAG_GET;
        requestUrl = requestUrl.replace("{projectId}", gitProjectId);
        requestUrl = requestUrl.replace("{tagName}", tagName);
        Map<String, String> header = new HashMap<>(1);
        header.put("PRIVATE-TOKEN", getToken(requestUrl));
        try {
            ResponseEntity<String> responseEntity = HttpUtils.get(requestUrl, header, String.class);
            log.info(JSONObject.toJSONString(responseEntity));
            return responseEntity.getStatusCode().is2xxSuccessful();
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 获取真正的git地址（根据应用服务git下载地址，获取git仓库地址）
     *
     * @return 具体git仓库地址
     */
    private static String getRealGitUrl(String gitUrl) {
        if (StringUtils.isEmpty(gitUrl)) {
            log.error("参数异常，无法打tag： {}", gitUrl);
            return "";
        }
        String realGitUrl;
        if (gitUrl.contains(SZ_GIT)) {
            realGitUrl = URL_MAP.get(SZ_GIT);
        } else if (gitUrl.contains(TZ_GIT)) {
            realGitUrl = URL_MAP.get(TZ_GIT);
        } else {
            log.error("未配置git仓库，无法打tag");
            return "";
        }
        return realGitUrl;
    }

    public static void setGpToken(String gpToken) {
        GitUtils.gpToken = gpToken;
    }

    public static void setGupaoToken(String gupaoToken) {
        GitUtils.gupaoToken = gupaoToken;
    }

    public static void setFrontendConfigGitUrl(String frontendConfigGitUrl) {
        GitUtils.frontendConfigGitUrl = frontendConfigGitUrl;
    }

    public static void setFrontendConfigApplicationName(String frontendConfigApplicationName) {
        GitUtils.frontendConfigApplicationName = frontendConfigApplicationName;
    }

    /**
     * 获取文件内容
     *
     * @param filePath 文件路径
     * @param branch   对应分支
     * @return
     */
    public static String getfileContent(String filePath, String branch) {
        Map<String, String> applicationMap = search(frontendConfigApplicationName, frontendConfigGitUrl);
        String projectId = applicationMap.get(frontendConfigApplicationName);
        if (projectId == null) {
            throw new ServiceException("该应用服务在git上不存在，无法获取文件内容");
        }
        String realGitUrl = getRealGitUrl(frontendConfigGitUrl);
        String requestUrl = realGitUrl + GIT_FILE;
        requestUrl = requestUrl.replace("{projectId}", projectId);
        try {
            requestUrl = requestUrl.replace("{filePath}", URLEncoder.encode(filePath, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error("文件路径encode编码异常, ", e);
            return "";
        }
        requestUrl = requestUrl.replace("{branch}", branch);
        try {
            log.info("getfileContent->requestUrl: {}", requestUrl);
            UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(requestUrl);
            HttpHeaders header = new HttpHeaders();
            header.set("PRIVATE-TOKEN", getToken(requestUrl));
            ResponseEntity<String> responseEntity = HttpUtils.exchange(uriComponentsBuilder.build(true).toUri(), HttpMethod.GET, header, String.class);
            JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
            String content = jsonObject.get("content").toString();
            content = new String(Base64.getDecoder().decode(content));
            return content;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static void main(String[] args) {
        String filePath = null;
        try {
            filePath = "fe_deploy/fe_chart/rp-fe-chart/conf/admin/server.config.json";
//            filePath = ".gitignore";
            filePath = URLEncoder.encode(filePath, "UTF-8");
//            filePath = "fe_deploy%2Ffe_chart%2Frp-fe-chart%2Fconf%2Fadmin%2Fserver.config.json";
        } catch (Exception e) {
            e.printStackTrace();
        }
////        String requestUrl = "https://gitlab.gupao.com/api/v4/projects/2756/repository/files/" + filePath + "?ref=master";
        String requestUrl = "https://gitlab.gupao.com/api/v4/projects/3376/repository/files/" + filePath + "?ref=prod";
////        String requestUrl = "https://gitlab.gupao.com/api/v4/projects/3376/repository/tree?ref=prod&path=fe_deploy/fe_chart/rp-fe-chart/conf/admin/";
//        System.out.println(requestUrl);


        HttpHeaders header = new HttpHeaders();
        header.set("PRIVATE-TOKEN", "yiQjPtqYSJrs3rqU62xK");
        try {
            System.out.println(requestUrl);
            UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(requestUrl);
            ResponseEntity<String> responseEntity = HttpUtils.exchange(uriComponentsBuilder.build(true).toUri(), HttpMethod.GET, header, String.class);
            JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
            System.out.println("jsonObject: " + jsonObject);
            String body = jsonObject.get("content").toString();
            body = new String(Base64.getDecoder().decode(body));
            System.out.println(body);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
